package com.lzj.demo.design.door.aspect;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.json.JSONUtil;
import com.lzj.demo.design.door.StarterService;
import com.lzj.demo.design.door.annotation.IsBlackList;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.lang.reflect.Method;
import java.util.Objects;

/**
 * 白名单切面逻辑
 * */
@Aspect
@Component
@Order(value = 1)
@Slf4j
public class IsBlackListAspect {
    @Resource
    private StarterService starterService;

    @Pointcut("@annotation(com.lzj.demo.design.door.annotation.IsBlackList)")
    public void aopPoint(){

    }

    @Around("aopPoint()")
    public Object doRouter(ProceedingJoinPoint jp)throws Throwable{
        //获取内容
        Method method = getMethod(jp);
        IsBlackList door = method.getAnnotation(IsBlackList.class);
        String keyValue = getFiledValue(door.key(), jp.getArgs());
        //获取字段值
        if(Objects.isNull(keyValue) || "".equals(keyValue)){
            return jp.proceed();
        }
        log.info("itstack door:method={},value={}",method.getName(),keyValue);
        //配置
        String[] split = starterService.spilt(",");
        //白名单过滤
        for (String str:split) {
            if(keyValue.equals(str)){
                return jp.proceed();
            }
        }
        //拦截
        return returnObject(door,method);
    }

    private Method getMethod(JoinPoint jp)throws NoSuchMethodException{
        Signature sig = jp.getSignature();
        MethodSignature methodSignature = (MethodSignature) sig;
        return getClass(jp).getMethod(methodSignature.getName(),methodSignature.getParameterTypes());
    }

    private Class<?>getClass(JoinPoint jp)throws NoSuchMethodException{
        return jp.getTarget().getClass();
    }

    //返回对象
    private Object returnObject(IsBlackList door , Method method)throws IllegalAccessException,InstantiationException {
        Class<?> returnType = method.getReturnType();
        String returnJson = door.returnJson();
        if("".equals(returnJson)){
            return returnType.newInstance();
        }
        return JSONUtil.parse(returnJson);
    }

    //获取属性值
    private String getFiledValue(String filed, Object[]args){
        String filedValue = null;
        try {
            for (Object arg:args) {
                if(Objects.isNull(filedValue) || "".equals(filedValue)){
                    filedValue = BeanUtil.getProperty(arg,filed);
                }else {
                    break;
                }
            }
        }catch (Exception e){
            if(args.length == 1){
                return args[0].toString();
            }
        }
        return filedValue;
    }
}
